package pervasivePositioning.ui;

import java.io.IOException;

import android.app.Activity;
import android.content.res.Configuration;
import android.location.Location;
import android.os.Bundle;
import android.os.Handler;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.CheckBox;
import android.widget.TextView;
import android.widget.Toast;
import pervasivePositioning.androidPositioner.PositionService;
import pervasivePositioning.pos.AccelerometerService;
import pervasivePositioning.pos.Coordinate;
import pervasivePositioning.pos.Positioner;
import pervasivePositioning.ui.R;
//import pervasivePositioning.ui.SettingsChangedWatcher;

public class UI extends Activity implements
	PositionService,
	AccelerometerService,
	StrategyController
{
	TextView longitude;
	TextView latitude;
	TextView accelerometerX, accelerometerY, accelerometerZ, inMotionView;
	View[] strategyButtons;
	View[] strategyProperties;
	
	Positioner positioner;
	Coordinate coordinate;
	float[] accelerometerValues;
	boolean isInMotion;

	final Handler updatehandler = new Handler();
	
	// Create runnable for posting
    final Runnable UpdateUI = new Runnable() {
        public void run() {
            setCoordinateFields();
        }
    };	

    @Override
	public void changeStrategy(int n, boolean enabled) {    	
    	positioner.setProperties(
    			(float) getField(strategyProperties[0]),
    			(float) getField(strategyProperties[1]),
    			(float) getField(strategyProperties[2]),
    			(float) getField(strategyProperties[3])
    	);
    	positioner.enableFilter(n, enabled);
	}
    
    private float getField(View v) {
    	float f = 0;
    	try {
    		String str = ((TextView) v).getText().toString();
	    	if (str.length() > 0) {
	    		f = Float.parseFloat(str);
	    	}
    	}
    	catch (NumberFormatException e) {
    		
    	}
    	
    	return f;
    }
    
    private void setCoordinateFields()
    {
    	if(coordinate != null) {
    		longitude.setText(String.valueOf(coordinate.x));		
    		latitude.setText(String.valueOf(coordinate.y));		    	
    	}
    	if(accelerometerValues != null){
       		accelerometerX.setText(String.valueOf(accelerometerValues[0]));
       		accelerometerY.setText(String.valueOf(accelerometerValues[1]));
       		accelerometerZ.setText(String.valueOf(accelerometerValues[2]));
       	}
    	inMotionView.setText(String.valueOf(isInMotion));
    }
	
    public void setPropertyFields() {
    	for (int i = 0; i < strategyButtons.length; i++) {
    		((CheckBox) strategyButtons[i]).setChecked(positioner.isStrategyEnabled(i));
    	}
    	for (int i = 0; i < strategyProperties.length; i++) {
    		((TextView) strategyProperties[i]).setText(String.valueOf(positioner.getProperty(i)));
    	}
    }
    
    public void getPropertyFields() {
    	for (int i = 0; i < strategyButtons.length; i++) {
    		positioner.enableFilter(i, ((CheckBox) strategyButtons[i]).isChecked());
    	}
    	for (int i = 0; i < strategyProperties.length; i++) {
    		positioner.setProperty(i, getField(strategyProperties[i]));
    	}
    }
    
    public void onCreate(Bundle savedInstanceState) {
    	super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        longitude = (TextView) findViewById(R.id.longitude);
        latitude = (TextView) findViewById(R.id.latitude);
        accelerometerX = (TextView) findViewById(R.id.accelerometerX);
        accelerometerY = (TextView) findViewById(R.id.accelerometerY);
        accelerometerZ = (TextView) findViewById(R.id.accelerometerZ);
        inMotionView = (TextView) findViewById(R.id.inMotion);
        
        strategyButtons = new View[]{
        		findViewById(R.id.timeButton),
        		findViewById(R.id.distanceButton),
        		findViewById(R.id.speedButton),
        		findViewById(R.id.motionButton)};
        strategyProperties = new View[]{
        		findViewById(R.id.time),
        		findViewById(R.id.distance),
        		findViewById(R.id.speed),
        		findViewById(R.id.accThreshold)
        };
        
        boolean demoMode = false;
        if(demoMode)
        {
        	latitude.setText("56.1558330059515");
        	longitude.setText("10,139120221138");
        	accelerometerX.setText("0.7627395");
        	accelerometerY.setText("-0.3405087");
        	accelerometerZ.setText("9.615966");
        	inMotionView.setText("true");
        	
        	String[] values = new String[]{"3","10","2","0.5"};
        	for(int i = 0; i < values.length; i++) {
        		((TextView) strategyProperties[i]).setText(values[i]);
        	}
        	((CheckBox) strategyButtons[0]).setChecked(true);
        	((CheckBox) strategyButtons[3]).setChecked(true);
        	return;
        }
        
        OnStrategyChangedListener strategyListener = new OnStrategyChangedListener(this, strategyButtons);
    	
    	for (View v : strategyProperties) {
    		((TextView) v).addTextChangedListener(new SettingsChangedWatcher(this));
    	}

        for (View v : strategyButtons) {
        	v.setOnClickListener(strategyListener);
        }

        reset();
        try {
			positioner = new Positioner((PositionService) this, (AccelerometerService) this, this);
			
	        positioner.enableListeners();
	        
		} catch (IOException e) {
			Toast.makeText(getBaseContext(), e.getLocalizedMessage(), Toast.LENGTH_LONG);
		}
    }
    
    @Override // to prevent oncreate to reanitilize everything when the orientation changes 
    public void onConfigurationChanged(Configuration newConfig) {
      super.onConfigurationChanged(newConfig);
    }    
    
	public void ReportPosition(long time, Coordinate loc, Coordinate acc, String config)
	{
		coordinate = loc;
		updatehandler.post(UpdateUI);
	}
	
	public boolean reportAccelerometer(float[] values, boolean inMotion) {
		accelerometerValues = values;
		isInMotion = inMotion;
		updatehandler.post(UpdateUI);
		
		return true;
	}
	
    public void onResume()
    {
    	super.onResume();
        if(positioner != null) {
        	setPropertyFields();
        	positioner.enableListeners();            	
        }
    }
    
    public void onPause()
    {
    	super.onPause();
        positioner.disableListeners();            	    	
    }
    
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.mainmenu, menu);
        return true;
    }
    
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.reset:
        	positioner.reset();
        	Toast.makeText(this, "Reset performed", Toast.LENGTH_SHORT).show();
            
            return true;

        case R.id.save:
        	try {
					positioner.save();
			} catch (IOException e) {
	        	Toast.makeText(this, String.format("%s\n%s", "Error saving", e.getMessage()), Toast.LENGTH_SHORT).show();
	        	return true;
			}
        
        	Toast.makeText(this, "Fixes saved", Toast.LENGTH_SHORT).show();
        	return true;
        	
        case R.id.send:
        	positioner.disableListeners();
        	try {
				positioner.send();
			} catch (IOException e) {
	        	Toast.makeText(this, String.format("%s\n%s", "Error sending", e.getMessage()), Toast.LENGTH_SHORT).show();
	        	return true;
			}
        	positioner.enableListeners();
        	
        	Toast.makeText(this, "Fixes sent", Toast.LENGTH_SHORT).show();

            return true;
        default:
        	return super.onOptionsItemSelected(item);
        }
    }

	@Override
	public void reset() {
		for (TextView v : new TextView[]{longitude, latitude, accelerometerX, accelerometerY, accelerometerZ, inMotionView}) {
			v.setText("");
		}

		coordinate = null;
		accelerometerValues = null;		
	}

	@Override
	public void save() {
		//Intentionally left blank
	}

	@Override
	public void send() {
		//Intentionally left blank
	}
}